package com.jdj.framework.dao.mybatis.service;

import com.jdj.framework.core.base.vo.BaseVo;
import com.jdj.framework.core.base.vo.PageInfo;
import com.jdj.framework.dao.mybatis.dao.MyBatisDao;
import com.jdj.framework.dao.mybatis.entity.BaseEntity;
import com.jdj.framework.dao.mybatis.entity.condition.BaseEntityCondition;
import java.io.Serializable;
import java.util.List;

/**
 * Service父类
 * @author caijinbang
 * @date 2019-04-14 13:34
 */
public interface BaseService {
    /**
     * 根据condition查询记录总数
     *
     * @param condition 条件
     * @return 影响行数
     */
    <Condition extends BaseEntityCondition> int countByCondition(Condition condition);

    /**
     * 根据condition批量查询
     *
     * @param condition 条件
     * @return 实体集合
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> List<Entity> selectByCondition(
        Condition condition);

    /**
     * 根据condition单个查询
     *
     * @param condition 条件
     * @return 实体
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> Entity selectOneByCondition(Condition condition);

    /**
     * 根据condition分页查询
     *
     * @param condition 条件
     * @return 分页对象
     */
    <Condition extends BaseEntityCondition> PageInfo selectPageByCondition(Condition condition);

    /**
     * 新增实体有值字段记录，返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int insert(Entity entity);

    /**
     * <pre>
     * 【推荐使用 insertList】
     * </pre>
     * 批量新增实体有值字段记录，返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    @Deprecated
    <Entity extends BaseEntity> int insert(List<Entity> entities);

    /**
     * 批量新增实体(如果主键为空，会提供一个32位字符)，返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    <Entity extends BaseEntity> int insertList(List<Entity> entities);

    /**
     * 新增实体有值字段记录，返回主键
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity, T> T insertWithPrimaryKey(Entity entity);

    /**
     * <pre>
     * 【推荐使用 insertListWithPrimaryKeys】
     * </pre>
     * 批量新增实体有值字段记录，返回主键集合
     *
     * @param entities 实体集合
     * @return 主键集合
     */
    @Deprecated
    <Entity extends BaseEntity> List<Serializable> insertWithPrimaryKeys(List<Entity> entities);

    /**
     * 批量新增实体(如果主键为空，会提供一个32位字符)，返回主键集合
     *
     * @param entities 实体集合
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> insertListWithPrimaryKeys(List<Entity> entities);

    /**
     * 新增实体有值字段记录，返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity insertWithQuery(Entity entity);

    /**
     * 批量新增实体有值字段记录，返回实体集合
     *
     * @param entities 实体
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> insertWithQuery(List<Entity> entities);

    /**
     * 根据主键删除
     *
     * @param entityClass     实体类
     * @param primaryKeyValue 主键值
     * @return 影响行数
     */
    <Entity extends BaseEntity> int deleteByPrimaryKey(Class<Entity> entityClass, Serializable primaryKeyValue);

    /**
     * 删除实体（Id不能为空），返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int delete(Entity entity);

    /**
     * 根据条件删除实体，返回行数
     *
     * @param condition 条件
     * @return 影响行数
     */
    int deleteByCondition(BaseEntityCondition condition);

    /**
     * 批量删除实体，返回行数
     *
     * @param entities 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int delete(List<Entity> entities);

    /**
     * 更新实体有值字段记录，返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int update(Entity entity);

    /**
     * 更新实体（字段 = null 或 字段 = "" 的不更新），返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotEmpty(Entity entity);

    /**
     * 更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotNull(Entity entity);

    /**
     * 根据条件更新实体有值字段记录，返回行数
     *
     * @param entity    实体
     * @param condition 条件
     * @return 影响行数
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> int updateByCondition(Entity entity,
        Condition condition);

    /**
     * 批量更新实体有值字段记录，返回行数
     *
     * @param entities 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int update(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 或 字段 = "" 的不更新），返回行数
     *
     * @param entities 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotEmpty(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回行数
     *
     * @param entities 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotNull(List<Entity> entities);

    /**
     * 更新实体有值字段记录，返回主键
     *
     * @param entity 实体
     * @return
     */
    <Entity extends BaseEntity, T> T updateWithPrimaryKey(Entity entity);

    /**
     * 更新实体（字段 = null 或 字段 = "" 的不更新），返回主键
     *
     * @param entity 实体
     * @return
     */
    <Entity extends BaseEntity, T> T updateNotEmptyWithPrimaryKey(Entity entity);

    /**
     * 更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回主键
     *
     * @param entity 实体
     * @return
     */
    <Entity extends BaseEntity, T> T updateNotNullWithPrimaryKey(Entity entity);

    /**
     * 批量更新实体有值字段记录，返回主键集合
     *
     * @param entities 实体
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> updateWithPrimaryKeys(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 或 字段 = "" 的不更新），返回主键集合
     *
     * @param entities 实体
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> updateNotEmptyWithPrimaryKeys(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回主键集合
     *
     * @param entities 实体
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> updateNotNullWithPrimaryKeys(List<Entity> entities);

    /**
     * 更新实体有值字段记录，返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity updateWithQuery(Entity entity);

    /**
     * 更新实体（字段 = null 或 字段 = "" 的不更新），返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity updateNotEmptyWithQuery(Entity entity);

    /**
     * 更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity updateNotNullWithQuery(Entity entity);

    /**
     * 批量更新实体有值字段记录，返回实体集合
     *
     * @param entities 实体
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> updateWithQuery(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 或 字段 = "" 的不更新），返回实体集合
     *
     * @param entities 实体
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> updateNotEmptyWithQuery(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回实体集合
     *
     * @param entities 实体
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> updateNotNullWithQuery(List<Entity> entities);

    /**
     * 保存实体，返回影响行数
     * <p>
     * 1、优先判断设置 rowState，区分 增加，删除，修改；
     * 2、其次判断主键字段是否有值，区分 增加，修改；
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int save(Entity entity);

    /**
     * 批量保存实体，返回影响行数
     * <p>
     * 1、优先判断设置 rowState，区分 增加，删除，修改；
     * 2、其次判断主键字段是否有值，区分 增加，修改；
     *
     * @param entities 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int save(List<Entity> entities);

    /**
     * 保存实体，返回保存后的实体
     * <p>
     * 1、优先判断设置 rowState，区分 增加，删除，修改；
     * 2、其次判断主键字段是否有值，区分 增加，修改；
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity saveWithQuery(Entity entity);

    /**
     * 批量保存实体，返回保存后的实体集合
     * <p>
     * 1、优先判断设置 rowState，区分 增加，删除，修改；
     * 2、其次判断主键字段是否有值，区分 增加，修改；
     *
     * @param entities 实体
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> saveWithQuery(List<Entity> entities);

    /**
     * 根据主键查询
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity selectByPrimaryKey(Entity entity);

    /**
     * 根据主键查询
     *
     * @param entityClass     实体
     * @param primaryKeyValue 主键
     * @return 实体
     */
    <Entity extends BaseEntity> Entity selectByPrimaryKey(Class<Entity> entityClass, Serializable primaryKeyValue);

    /**
     * VO 转换 Entity
     *
     * @param clazz Entity Class
     * @param vo VO 对象
     * @param <Entity> BaseEntity 的子类（泛型约束）
     * @param <VO> BaseVO 的子类（泛型约束）
     * @return Entity 对象
     */
    <Entity extends BaseEntity, VO extends BaseVo> Entity toEntity(Class<Entity> clazz, VO vo);

    /**
     * VO集合 转换 Entity集合
     * @param clazz Entity Class
     * @param vos   VO 对象集合
     * @param <Entity>  BaseEntity 的子类（泛型约束）
     * @param <VO>  BaseVO 的子类（泛型约束）
     * @return  Entity 对象集合
     */
    <Entity extends BaseEntity, VO extends BaseVo> List<Entity> toEntities(Class<Entity> clazz, List<VO> vos);

    /**
     *  Entity 转换 VO
     * @param clazz VO Class
     * @param entity    Entity 对象
     * @param <Entity>  BaseEntity 的子类（泛型约束）
     * @param <VO>  BaseVO 的子类（泛型约束）
     * @return VO 对象
     */
    <Entity extends BaseEntity, VO extends BaseVo> VO toVO(Class<VO> clazz, Entity entity);

    /**
     *  Entity集合 转换 VO集合
     * @param clazz VO Class
     * @param entities    Entity 对象集合
     * @param <Entity>  BaseEntity 的子类（泛型约束）
     * @param <VO>  BaseVO 的子类（泛型约束）
     * @return VO 对象集合
     */
    <Entity extends BaseEntity, VO extends BaseVo> List<VO> toVOs(Class<VO> clazz, List<Entity> entities);

    /**
     * 获取 MyBatisDao Dao对象
     * 【推荐 getDao()】
     *
     * @return
     */
    @Deprecated
    MyBatisDao getMyBatisDao();

    /**
     * 获取 MyBatisDao Dao对象
     *
     * @return
     */
    MyBatisDao getDao();
}
